package java802;

import java8.Employee;
import org.junit.Test;

import java.io.PrintStream;
import java.util.function.*;

//1 方法引用:如果Lambda体中的功能,已经有方法提供了实现,就可以使用方法引用
//          //可以将方法引用理解为lambda表达式的另外一种表现形式

/**
 * 1 对象的引用:: 实例方法名
 * 2  类名:: 静态方法名
 * 3  类名:: 实例方法名
 * 注: 1 方法引用所引用的参数列表与返回值类型,必须要和函数式接口的一致
 */
public class TestMethodRef01 {
	
	//1 对象的引用::实例方法名
	@Test
	public void test01(){
		//System.out实例是打印流对象
		PrintStream ps = System.out;
		Consumer<String> com1= x->ps.println(x);
		
		//上面可以写成方法引用: 不需要写->和参数
		Consumer<String> com2=ps::println;
		Consumer<String> com3= System.out::println;
		com1.accept("hello1");
		com2.accept("hello2");
		com3.accept("hello3");
	}
	@Test
	public void test02(){
		Employee emp=new Employee("哈哈",18);
		Supplier<String> sup1=()->emp.getName();
		//getName已经实现,可以使用方法引用
		Supplier<String> sup2=emp::getName;
		System.out.println(sup1.get());//哈哈
		System.out.println(sup2.get());//哈哈
	}
	//2 类名::静态方法名
	@Test
	public void test03(){
		//返回两个值中大的一个  BiFunction:接受两个类型参数,返回一个类型值
		BiFunction<Double, Double, Double> bif1=(x, y)-> Math.max(x,y);
		Double apply = bif1.apply(1.5, 2.8);//2.8
		System.out.println(apply);
		//使用方法引用
		BiFunction<Double, Double, Double> bif2= Math::max;
		System.out.println(bif2.apply(1.5, 2.8));//2.8
		
	}
	
	//3 类名::实例方法名
	@Test
	public void test04(){
		//比较两个字符串是否相等 BiPredicate: 传入两个参数
		BiPredicate<String, String> bq1=(x, y)->x.equals(y);
		bq1.test("哈哈","哈哈");
		//如果lambda的第一个参数是方法的调用者,第二个参数没有或者是实例方法,可以直接用类名::实例方法
		BiPredicate<String, String> bq2= String::equals;
		bq2.test("哈哈","哈哈");
	}
	//4 构造方法引用    :构造器的参数列表需要与函数式接口一致
	@Test
	public void test05(){
		// 1 类名::new   
		Supplier<Employee> sup1=()->new Employee();
		//引用构造器  无参构造器
		Supplier<Employee> sup2=Employee::new;
		//一个参数构造器
		Function<String,Employee> sup3=Employee::new;
		//两个参数构造器
		BiFunction<String, Integer,Employee> sup4=Employee::new;
	}
	//数组引用
	@Test
	public void test06(){
		//创建数组
		Function<Integer, String[]> fun= length->new String[length];
		String[] apply = fun.apply(10);
		System.out.println(apply.length);//10
		//引用数组
		Function<Integer, String[]> fun1= String[]::new;
		String[] apply1 = fun.apply(5);
		System.out.println(apply1.length);//5
	}
}
